package com.ruoyi.system.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.redis.RedisKey;
import com.ruoyi.system.domain.BsCity;
import com.ruoyi.system.domain.BsProvince;
import com.ruoyi.system.domain.dto.LitterBsAreaDTO;
import com.ruoyi.system.domain.dto.SysAddressDTO;
import com.ruoyi.system.domain.sysutil.LongitudeLatitude;
import com.ruoyi.system.mapper.BsCityMapper;
import com.ruoyi.system.mapper.BsProvinceMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.BsAreaMapper;
import com.ruoyi.system.domain.BsArea;
import com.ruoyi.system.service.IBsAreaService;

/**
 * 地区设置Service业务层处理
 * 
 * @author ruoyi
 * @date 2020-11-05
 */
@Service
public class BsAreaServiceImpl implements IBsAreaService 
{
    @Autowired
    private BsAreaMapper bsAreaMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private BsCityMapper bsCityMapper;

    @Autowired
    private BsProvinceMapper bsProvinceMapper;

    /**
     * 查询地区设置
     * 
     * @param areaId 地区设置ID
     * @return 地区设置
     */
    @Override
    public BsArea selectBsAreaById(Long areaId)
    {
        return bsAreaMapper.selectBsAreaById(areaId);
    }

    /**
     * 查询地区设置列表
     * 
     * @param bsArea 地区设置
     * @return 地区设置
     */
    @Override
    public List<BsArea> selectBsAreaList(BsArea bsArea)
    {
        return bsAreaMapper.selectBsAreaList(bsArea);
    }

    @Override
    public List<LitterBsAreaDTO> selectBsAreaListShort(String cityCode,String areaName) {
        return bsAreaMapper.selectBsAreaListShort(cityCode,areaName);
    }

    /**
     * 新增地区设置
     * 
     * @param bsArea 地区设置
     * @return 结果
     */
    @Override
    public int insertBsArea(BsArea bsArea)
    {
        return bsAreaMapper.insertBsArea(bsArea);
    }

    /**
     * 修改地区设置
     * 
     * @param bsArea 地区设置
     * @return 结果
     */
    @Override
    public int updateBsArea(BsArea bsArea)
    {
        return bsAreaMapper.updateBsArea(bsArea);
    }

    /**
     * 批量删除地区设置
     * 
     * @param areaIds 需要删除的地区设置ID
     * @return 结果
     */
    @Override
    public int deleteBsAreaByIds(Long[] areaIds)
    {
        return bsAreaMapper.deleteBsAreaByIds(areaIds);
    }

    /**
     * 删除地区设置信息
     * 
     * @param areaId 地区设置ID
     * @return 结果
     */
    @Override
    public int deleteBsAreaById(Long areaId)
    {
        return bsAreaMapper.deleteBsAreaById(areaId);
    }


    @Override
    public BsArea getAreaByLgla(String lgla) {
        LongitudeLatitude coordinateByLgla = LongitudeLatitude.getCoordinateByLgla(lgla);
        if(!redisCache.isHasKey(RedisKey.GEO_SYSTEM_AREA)){
            List<BsArea> bsAreas = bsAreaMapper.selectBsAreaList(null);
            for (BsArea tmp : bsAreas
            ) {
                if(StringUtils.isNotEmpty(tmp.getLng()) && StringUtils.isNotEmpty(tmp.getLat())){
                    LongitudeLatitude tmplgla = LongitudeLatitude.getCoordinateByLgla(tmp.getLng() + "," + tmp.getLat());
                    if(coordinateByLgla != null && coordinateByLgla.getLongitude() != null && coordinateByLgla.getLatitude() !=null){
                        redisCache.redisGeoAdd(RedisKey.GEO_SYSTEM_AREA,tmplgla.getLongitude(),tmplgla.getLatitude(),tmp.getAreaId()+"");
                    }
                }
            }
        }
        GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = redisCache.redisNearByXY(RedisKey.GEO_SYSTEM_AREA, coordinateByLgla.getLongitude(),coordinateByLgla.getLatitude(), 1000, 1);
        Long areaId =0l ;
        for (GeoResult<RedisGeoCommands.GeoLocation<String>> geo : geoResults
        ) {
            //获取附近的客户id
            areaId = StringUtils.isNotEmpty(geo.getContent().getName()) ? Long.parseLong(geo.getContent().getName()) : 0l;
        }
        BsArea bsArea = bsAreaMapper.selectBsAreaById(areaId);
        return bsArea;
    }


    @Override
    public SysAddressDTO getAddressCodeByArea(BsArea bsArea) {
        if(bsArea!=null) {
            Map<String, SysAddressDTO> map = redisCache.getCacheMap(RedisKey.GEO_SYSTEM_AREA_OBJECT + bsArea.getAreaCode());
            Object data= map.get(RedisKey.GEO_SYSTEM_AREA_OBJECT + bsArea.getAreaCode());
            ObjectMapper mapper = new ObjectMapper();
            SysAddressDTO sysAddressDTO = mapper.convertValue(data,SysAddressDTO.class);
            if (sysAddressDTO == null) {
                sysAddressDTO=new SysAddressDTO();
                BsCity tmpCity = new BsCity();
                tmpCity.setCityCode(bsArea.getCityCode());
                List<BsCity> bsCities = bsCityMapper.selectBsCityList(tmpCity);
                if (bsCities != null && bsCities.size()>0) {
                    BsCity bsCity = bsCities.get(0);
                    sysAddressDTO.setBsCity(bsCity);
                    BsProvince tmpProvince = new BsProvince();
                    tmpProvince.setProvinceCode(bsCity.getProvinceCode());
                    List<BsProvince> bsProvinces = bsProvinceMapper.selectBsProvinceList(tmpProvince);
                    if (bsProvinces != null && bsProvinces.size() >0) {
                        BsProvince bsProvince = bsProvinces.get(0);
                        sysAddressDTO.setBsProvince(bsProvince);
                    }
                }
                map.put(RedisKey.GEO_SYSTEM_AREA_OBJECT + bsArea.getAreaCode(), sysAddressDTO);
                redisCache.setCacheMap(RedisKey.GEO_SYSTEM_AREA_OBJECT + bsArea.getAreaCode(), map);
                return sysAddressDTO;
            }
            System.out.println("getAddressCodeByArea>>>>>>>>>>>>>>>cachecachecachecachecachecachecachecache"+sysAddressDTO);
            return sysAddressDTO;
        }
        return null;
    }
}
